#pragma once
#include "token.hpp"
#include "ast.hpp"
#include <vector>
#include <memory>
#include <string>

struct Parser {
    std::vector<Token> t;
    int i = 0;
    std::string prevIdent;

    Parser(std::vector<Token> tokens);

    std::unique_ptr<Stmt> parseOne();
    std::unique_ptr<Stmt> parseCreate();
    std::unique_ptr<Stmt> parseInsert();
    std::unique_ptr<class SelectStmt> parseSelect();
    std::unique_ptr<Stmt> parseDelete();
    std::unique_ptr<Stmt> parseDrop();
    std::unique_ptr<Stmt> parseAlter();
    std::unique_ptr<Stmt> parseCreateIndex();
    std::unique_ptr<Stmt> parseShow();
    std::unique_ptr<Stmt> parseUpdate();
    void expectIdent();
    std::string expectInt();
    struct InsertStmt::Val parseValue();
    std::unique_ptr<class Condition> parseCondition();

    std::unique_ptr<Condition> parseOrCondition();

    std::unique_ptr<Condition> parseAndCondition();

    std::unique_ptr<Condition> parsePrimaryCondition();

    std::unique_ptr<Condition> parseSimpleCondition();

    ColumnDef parseColumnType(const std::string &colName);

private:
    std::string here(const Token &tok);
    Token &peek();
    Token &get();
    bool accept(TokType tp, std::string lex="");
    void expect(TokType tp, std::string lex="");
};
